`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/10/23 22:07:28
// Design Name: 
// Module Name: sync
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module sync
#(
    localparam PORCH_WIDTH  = 16,
    localparam SIGNAL_WIDTH = 8,
    localparam FMC_CMD_WIDTH = 8
)
(
     input clkDiv, 
     input rst, 
     input lcd_en, 
     input ddr_ready, 
     input [PORCH_WIDTH-1:0] H_P, 
     input [PORCH_WIDTH-1:0] V_P, 
     input [PORCH_WIDTH-1:0] H_S, 
     input [PORCH_WIDTH-1:0] V_S, 
     input [PORCH_WIDTH-1:0] H_F, 
     input [PORCH_WIDTH-1:0] H_B, 
     input [PORCH_WIDTH-1:0] V_F, 
     input [PORCH_WIDTH-1:0] V_B, 
   
     output reg vs, 
     output reg hs, 
     output reg DE,  
     output vsync_de,
     output hsync_de,  
     output fifo_first_read,
     output fifo_rerun,
     output reg[PORCH_WIDTH-1:0] x_cnt,
     output reg[PORCH_WIDTH-1:0] y_cnt,
     input [SIGNAL_WIDTH-1:0] signal_open,
     input [SIGNAL_WIDTH-1:0] HV_Sync,
     input Display_Mode,
     input MCU_WR,
     input MCU_RS, 
     input MCU_LOGIC_EN,
     input rs_logic,   
     input wr_logic
);
reg           vsync_r;
reg           hsync_r;
reg           de_r; 
reg           h_en;

reg           vsync_de_r;
reg           hsync_de_r;
reg           first_read_r;
reg           fifo_rerun_r;

reg [PORCH_WIDTH-1:0]    h_count;
reg [PORCH_WIDTH-1:0]    v_count;


always @(posedge clkDiv or posedge rst)   begin
     if (rst)    begin
         h_count <= 16'd0;
         v_count <= 16'd0;
         hsync_de_r <= 1'b0;
         vsync_de_r <= 1'b0;
         first_read_r <= 1'b0;
     end
     else if(~Display_Mode)   begin
         if (lcd_en == 1'b0)   begin
             h_count <= 16'd0;
             v_count <= 16'd0;
             vsync_de_r <= 1'b0;
             hsync_de_r <=1'b0;
             first_read_r <= 1'b0;
         end
         else  begin
             if (h_count == H_P + H_F + H_S + H_B - 1)   h_count <= 16'd0;
             else  h_count <= h_count + 1;  
                 
             if (v_count == V_P + V_F + V_S + V_B - 1 & h_count == H_P + H_F + H_S + H_B - 1) 
                v_count <= 16'd0; 
             else if (h_count == H_P + H_F + H_S + H_B - 1) 
                v_count <= v_count + 1;
                
             hsync_r <= ((h_count >= H_P + H_F) & (h_count < H_P + H_F + H_S)) ? HV_Sync[2]:~HV_Sync[2]; 
             vsync_r <= ((v_count >= V_P + V_F) & (v_count < V_P + V_F + V_S)) ? HV_Sync[3]:~HV_Sync[3];
             
             hsync_de_r <=  h_en;  h_en <= (h_count > 0 & h_count <= H_P) ? 1'b1 : 1'b0;    
             vsync_de_r <= (v_count > 0 & v_count <= V_P) ? 1'b1 : 1'b0;
             de_r <= hsync_de_r & vsync_de_r;
             
             fifo_rerun_r <= (v_count >= 0 & v_count <= V_P) ? 1'b1 : 1'b0;
         //  fifo_rerun_r <= (v_count == V_P + V_F + V_S + V_B - 1 & h_count == H_P + H_F + H_S + H_B - 1) ? 1'b1 : 1'b0;
             first_read_r <= (v_count == 0 & h_count == H_P + H_F + H_S + H_B - 1 - 8) ? 1'b1 : 1'b0;
         end
     end
end

always @(posedge clkDiv or posedge rst)
    if (rst == 1'b1)  begin
         DE <= 1'b0;
         hs <= 1'b0;
         vs <= 1'b0;
    end
    else if(~Display_Mode)   begin
         if (signal_open == 8'h01)   begin
             DE <= HV_Sync[1] == 1'b0 ? de_r :~de_r;
             hs <= hsync_r;
             vs <= vsync_r;
         end
         else  begin         
             vs <= 1'b0;
             hs <= 1'b0;
             DE <= 1'b0;
         end
     end
     else  begin //MCU 
        if(~MCU_LOGIC_EN)  begin    
             vs <= wr_logic;
             DE <= rs_logic;
        end
        else    begin
             vs <= MCU_WR;
             DE <= MCU_RS;
        end
     end
     
    
always @(posedge clkDiv or posedge rst)   begin
     if (rst)    begin
        x_cnt <= 16'd0;
        y_cnt <= 16'd0;
     end
     else if(~Display_Mode)   begin
         if (lcd_en == 1'b0)   begin
            x_cnt <= 16'd0;
            y_cnt <= 16'd0;
         end
         else begin
             if (x_cnt == H_P + H_F + H_S + H_B - 1)   x_cnt <= 16'd0;
             else  x_cnt <= x_cnt + 1;      
             if (y_cnt == V_P + V_F + V_S + V_B - 1 & x_cnt == H_P + H_F + H_S + H_B - 1)  y_cnt <= 16'd0; 
             else if (x_cnt == H_P + H_F + H_S + H_B - 1)  y_cnt <= y_cnt + 1;
         end 
    end
end

assign hsync_de = hsync_de_r;   
assign vsync_de = vsync_de_r;
assign fifo_first_read = first_read_r; //data process
assign fifo_rerun = fifo_rerun_r; //fifo ctrl
endmodule
